Post

Replies

Boosts

Views

Activity

SwiftUI - UISearchBar
I'm trying to use "searchText" as a parameter of a function to make an API call but after I type the name of the city and press search nothing happens. The API works fine with the initial value "Toronto" when the app first launches. Any suggestion ? import SwiftUI import UIKit   func fetchWeather(cityName: String) {     let urlString = "\(weatherURL)&query=\(cityName)"     getWeatherData(with: urlString)   } @State private var searchText = "Toronto" var body: some View { VStack { SearchBar(text: $searchText) }.onAppear() { self.fetchWeather(cityName: self.searchText) } } } struct SearchBar: UIViewRepresentable {      @Binding var text: String      class Coordinator: NSObject, UISearchBarDelegate {     @Binding var text: String     init(text: Binding<String>) {       _text = text     }     func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {       text = searchText     }   }   func makeCoordinator() -> SearchBar.Coordinator {     return Coordinator(text: $text)   }   func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {     let searchBar = UISearchBar(frame: .zero)     searchBar.delegate = context.coordinator     searchBar.searchBarStyle = .minimal     return searchBar   }   func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {     uiView.text = text   } }
6
0
1.6k
Aug ’20
PHImageManager.default().requestImage Error
Hi, any idea why I am getting an error in line "21" ? Thank you. final func chooseLastImage(_ sender: Any) {     let imgManager = PHImageManager.default()     let fetchOptions = PHFetchOptions()     let requestOptions = PHImageRequestOptions()     requestOptions.version = .original 10.     requestOptions.isSynchronous = false     requestOptions.isNetworkAccessAllowed = false     let targetSize: CGSize? = CGSize(width: photoImageView.bounds.width, height: photoImageView.bounds.height)     fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)]     let fetchResult: PHFetchResult&lt;PHAsset&gt; = PHAsset.fetchAssets(with: .image, options: fetchOptions) 20. 21.     imgManager.requestImage(for: fetchResult.lastObject!, targetSize: targetSize!, contentMode: .aspectFit, options: requestOptions) { (result, info) in 22. 23.       guard let result = result else { return } 24. 25.       DispatchQueue.main.async(execute: { 26. 27.         self.pickedImage = result 28. 29.         self.photoImageView.image = self.pickedImage 30. 31.       }) 32. 33.     } 34. 35.   } 36. 37. extension PhotoViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { 38. 39.   func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 40. 41.     if let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage { 42. 43.         photoImageView.image = updatedImage 44. 45.     } else if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { 46. 47.       pickedImage = image 48. 49.       photoImageView.image = pickedImage 50. 51.     } 52. 53.       dismiss(animated: true, completion: nil) 54. 55.     } 56. 57.     func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 58. 59.       dismiss(animated: true, completion: nil) 60. 61.   } 62. 63. }
0
0
537
Jul ’20
Show Activity Indicator before Segue.
Hello, I have been trying to show the activityIndicator I have set up before the segue to another viewController. When I tap the button for segue, the app gets into the inactive state for at least 5 seconds. I'm aiming to show the activityIndicator before the view freezes. There is no problem with the setup of the activityIndicator. The problem I'm having is the activityIndicator shows up after the segue on the other viewController. Thanks in advance.import UIKit class StitchEffectViewController: UIViewController { // @IBOutlet weak var activityIndicator: UIActivityIndicatorView! let stitchPhotoID = "StitchPhotoID" @IBOutlet weak var tapAboveOutlet: UIButton! override func viewDidLoad() { super.viewDidLoad() // activityIndicator.isHidden = true // activityIndicator.hidesWhenStopped = true } // override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { // super.viewWillTransition(to: size, with: coordinator) // // if UIApplication.shared.applicationState == .inactive { // Spinner.update() // } // // } @IBAction func tapAbove(_ sender: UIButton) { Spinner.start(style: .large, backColor: UIColor.white, baseColor: UIColor.green) spinnerSetup() } func spinnerSetup() { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: { self.performSegue(withIdentifier: self.stitchPhotoID, sender: nil) }) } }
7
0
1.8k
Jun ’20
Performance Issues due to Repetition
Hello, I have set up 16 CIFilter effects and for each effect I have created methods with identical functionality and due to the repetition I've been going through performance issues. The build time takes around 10-13 seconds. I have created a method called "applyFilterTo" to integrate the CIFilters under this method but then the filters started not to work anymore. Could you please give me some insight about how I can increase the performance of the app ?func effectsSliderSepiaTone() { sliderControl.addTarget(self, action: #selector(sliderSepiaToneDidChange(_:image:_:)), for: .allTouchEvents) sliderControl.translatesAutoresizingMaskIntoConstraints = false sliderControl.minimumValue = 0 sliderControl.maximumValue = 1 sliderControl.isContinuous = true sliderControl.tintColor = UIColor.blue view.addSubview(sliderControl) NSLayoutConstraint.activate([ sliderControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30), sliderControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30), sliderControl.bottomAnchor.constraint(equalTo: resetConfirmCollectionView.topAnchor, constant: -50)]) } func imageSepiaTone(imgView: UIImageView, sliderValue: CGFloat, image: UIImage){ let aCGImage = image.cgImage let aCIImage = CIImage(cgImage: aCGImage!) let sepiaToneFilter = CIFilter(name: "CISepiaTone") sepiaToneFilter!.setDefaults() sepiaToneFilter?.setValue(aCIImage, forKey: kCIInputImageKey) sepiaToneFilter?.setValue(sliderValue - 0.5, forKey: kCIInputIntensityKey) let outputImage = sepiaToneFilter?.outputImage! let cgimg = context.createCGImage(outputImage!, from: outputImage!.extent) let newUIImage = UIImage(cgImage: cgimg!, scale: image.scale, orientation: image.imageOrientation) imgView.image = newUIImage } @objc private func sliderSepiaToneDidChange(_ sender: UISlider!, image: UIImage,_ event: UIEvent) { if let touchEvent = event.allTouches?.first { switch touchEvent.phase { case .moved: labelControl.text = String(displayInPercentage) if updatedImage == nil { photoImageView.image = pickedImage imageSepiaTone(imgView: photoImageView, sliderValue: CGFloat(sender.value), image: pickedImage!) } else { photoImageView.image = updatedImage imageSepiaTone(imgView: photoImageView, sliderValue: CGFloat(sender.value), image: updatedImage!) } case .ended: updatedImage = photoImageView.image UserDefaults.standard.setValue(sliderControl.value, forKey: "slider_sepiatone") default: break } } labelControl.textAlignment = .center labelControl.numberOfLines = 0 labelControl.textColor = UIColor.gray labelControl.font = UIFont.systemFont(ofSize: 16) labelControl.translatesAutoresizingMaskIntoConstraints = false view.addSubview(labelControl) NSLayoutConstraint.activate([labelControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30), labelControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30), labelControl.bottomAnchor.constraint(equalTo: resetConfirmCollectionView.topAnchor, constant: -80)]) }class Effects { var context: CIContext! = CIContext(options: [.workingColorSpace: NSNull(), .outputColorSpace: NSNull()]) var currentFilter: CIFilter! struct Filter { let filterName: String var filterEffectValue: Any? var filterEffectValueName: String? init(filterName: String, filterEffectValue: Any?, filterEffectValueName: String?) { self.filterName = filterName self.filterEffectValue = filterEffectValue self.filterEffectValueName = filterEffectValueName } func applyFilterTo(image: UIImage, filterEffect: Filter, sliderValue: CGFloat?) -&gt; UIImage? { guard let cgImage = image.cgImage else { return nil } // let context = CIContext(options: nil) let ciImage = CIImage(cgImage: cgImage) currentFilter = CIFilter(name: filterEffect.filterName) currentFilter!.setDefaults() if currentFilter == CIFilter(name: "CIUnsharpMask") { currentFilter?.setValue(ciImage, forKey: kCIInputImageKey) currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputIntensityKey) } else if currentFilter == CIFilter(name: "CIGaussianBlur") { // currentFilter!.setDefaults() currentFilter?.setValue(ciImage, forKey: kCIInputImageKey) currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputRadiusKey) } else if currentFilter == CIFilter(name: "CICMYKHalftone") { // currentFilter!.setDefaults() currentFilter?.setValue(ciImage, forKey: kCIInputImageKey) currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputWidthKey) } else { currentFilter?.setValue(ciImage, forKey: kCIInputImageKey) if let filterEffectValue = filterEffect.filterEffectValue, let filterEffectValueName = filterEffect.filterEffectValueName { currentFilter?.setValue(filterEffectValue, forKey: filterEffectValueName) } } var filteredImage: UIImage? if let output = currentFilter?.value(forKey: kCIOutputImageKey) as? CIImage, let cgiImageResult = context.createCGImage(output, from: output.extent) { filteredImage = UIImage(cgImage: cgiImageResult, scale: image.scale, orientation: image.imageOrientation) } return filteredImage } }
4
0
609
Jun ’20
Changing the numberOfItemsInSection of a collectionView, from another collectionView didSelectSelectItemAt indexPath.
Hi, I have 2 separate collectionViews and I've been trying to change the numberOfItemsInSection of "collectionViewA" according to the didSelectItemAt indexPath of "collectionViewB". Let's say I have 2 items already setup in "collectionViewA" but if I select "collectionViewB" indexPath.row = 1, I would like to have 3 items in "collectionViewA", and if I select "collectionViewB" indexPath.row = 2, I would like to have 4 items in "collectionViewA". As far as I can see, this is possible but I couldn't find the relevant info online. Any idea on this please ?
17
0
3.1k
May ’20
Removing UISegmentedControl through collectionView didSelect
Hi, I have a UISegmentedControl implemented programmatically that I would like to remove from the screen when I select collectionView didSelect. I've tried many solutions but couldn't get success. Any advice on that please ? Sharing the relevant code;import Foundation import UIKit import Photos class PhotoViewController: UIViewController, UIScrollViewDelegate { func effectsSegmentedControl() { let items = ["Brightness", "Contrast", "Saturation", "Noise"] let segmentedControl = UISegmentedControl(items: items) segmentedControl.addTarget(self, action: #selector(effectsDidChange(_:)), for: .valueChanged) segmentedControl.translatesAutoresizingMaskIntoConstraints = false view.addSubview(segmentedControl) NSLayoutConstraint.activate([ segmentedControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30), segmentedControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30), segmentedControl.bottomAnchor.constraint(equalTo: resetConfirmCollectionView.topAnchor, constant: -10)]) } @objc func effectsDidChange(_ segmentedControl: UISegmentedControl) { switch segmentedControl.selectedSegmentIndex { case 0: effectsSliderBrightness() case 1: effectsSliderContrast() // sliderLabel(myText: "") case 2: effectsSliderSaturation() // sliderLabel(myText: "") case 3: effectsSliderNoise() // sliderLabel(myText: "") default: break } } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if collectionView == resetConfirmCollectionView { if indexPath.row == 0 { // photoImageView.image = pickedImage resetConfirmCollectionView.isHidden = true menuStackView.isHidden = false } if indexPath.row == 1 { // filteredImage = pickedImage resetConfirmCollectionView.isHidden = true menuStackView.isHidden = false } } }
3
0
612
Apr ’20
Setting Slider Value through UIPanGestureRecognizer
Hi, I've been trying to set the slider value in the same direction with finger drag movement on the screen. From right to left, decrease the slider value and vice versa. I have set up the slider outlet and the UIPanGestureRecognizer. I'm having trouble with assigning the slider thumbRect on "addPanGesture(slider: UISlider)" method when I call it. If I assign the slider, the whole slider starts moving. I'm aiming to move the thumbRect in accordance with the UIPanGestureRecognizer. I'm sharing the relevant code. In case, you need the whole code, I'd be more than happy to share it with you. Any suggestion please ?class PhotoViewController: UIViewController { @IBOutlet weak var effectsSlider: UISlider! var initialCenter: CGPoint! override func viewDidLoad() { super.viewDidLoad() initialCenter = effectsSlider.frame.origin } func addPanGesture(slider: UISlider) { let pan = UIPanGestureRecognizer(target: self, action: #selector(PhotoViewController.handlePan(sender:))) view.addGestureRecognizer(pan) } @objc func handlePan(sender: UIPanGestureRecognizer) { let panView = sender.view! let translation = sender.translation(in: view) switch sender.state { case .began, .changed: panView.center = CGPoint(x: panView.center.x + translation.x, y: panView.center.y + translation.y) sender.setTranslation(CGPoint.zero, in: view) case .ended: return default: break } } }
2
0
1k
Apr ’20
systemImage Configuration Size
Hello, I have been having trouble with configuring the systemImage size. I took a number of approaches but couldn't manage to set a size to the systemImage within the collectionView cell. Because of this, the text which is supposed to be below the image, clashes with the image due to its large size within the cell. The last approach I took with the code I'm sharing, I get an empty cell. Otherwise, I can't find a way to change the systemImage size. Could you please advise me regarding the configuration of systemImage ?Many Thanks.func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell { if collectionView == collectionViewEffects { let cellEffects = collectionView.dequeueReusableCell(withReuseIdentifier: "EffectsCell", for: indexPath) as! CustomEffectsCell collectionView.backgroundColor = .systemGray6 if indexPath.row == 0 { cellEffects.effectsLabel = "A" let config = UIImage.SymbolConfiguration(pointSize: 0, weight: .ultraLight) let cellImage = UIImage(systemName: "slider.horizontal.3", withConfiguration: config) let width = ((cellImage?.size.width)!)/4 let height = ((cellImage?.size.height)!)/4 guard let context = UIGraphicsGetCurrentContext() else { print("could not get graphics context") return cellEffects } context.setStrokeColor(UIColor.yellow.cgColor) context.setLineWidth(2) context.stroke(cellImage?.cgImage as! CGRect) cellImage?.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) cellEffects.effectsImage = cellImage self.view.addSubview(cellEffects) }
11
0
3.7k
Apr ’20
UICollectionView didSelectItemAt
Hi, I've been trying to set the "photoImageView.image" to the image "cell.bgImage" within the collectionView indexPath based on the selection. With a tap on the collectionView's image cells, I want the photoImageView.image to change according to the tapped image cell. I have tried many ways but couldn't get success. I believe the most feasible way is implementing this in "collectionView didSelectItemAt". Any help please ?Thank you.import Foundationimport UIKitimport Photosclass PhotoViewController: UIViewController { @IBOutlet weak var photoImageView: UIImageView! @IBOutlet var photoView: UIView! @IBOutlet weak var menuStackView: UIStackView! var imagePicker = UIImagePickerController() var effects = Effects() override func viewDidLoad() { super.viewDidLoad() imagePicker.delegate = self assignTap() view.addSubview(collectionView) collectionView.backgroundColor = .white collectionView.topAnchor.constraint(equalTo: photoImageView.bottomAnchor, constant: 110).isActive = true collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 10).isActive = true collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -103).isActive = true collectionView.clipsToBounds = true collectionView.dataSource = self collectionView.delegate = self collectionView.isHidden = false } @IBAction func previewTapped(_ sender: UIButton) { sender.pulsate() if collectionView.isHidden == true { collectionView.isHidden = false } else { collectionView.isHidden = true } } @IBAction func effectsTapped(_ sender: UIButton) { sender.flash() } @IBAction func exportTapped(_ sender: UIButton) { sender.shake() } func assignTap() { let tap = UITapGestureRecognizer(target: self, action: #selector(touchTapped(_:))) photoView.addGestureRecognizer(tap) } @objc func touchTapped(_ sender: UITapGestureRecognizer) { if collectionView.isTracking == false { if menuStackView.isHidden == false { collectionView.isHidden = true menuStackView.isHidden = true } else { menuStackView.isHidden = false collectionView.isHidden = false } } } func chooseImage(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { imagePicker.sourceType = .photoLibrary imagePicker.allowsEditing = true self.present(imagePicker,animated: true, completion: nil) } } func accessVideo(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.camera) { imagePicker.sourceType = .camera self.present(imagePicker, animated: true, completion: nil) } else { print("Camera not available") } } public func chooseLastImage(_ sender: Any) { print("photoImageView", photoImageView!) print("photoImageView.bounds", photoImageView.bounds) let targetSize: CGSize? = CGSize(width: photoImageView.bounds.width, height: photoImageView.bounds.height) let options = PHImageRequestOptions() options.isNetworkAccessAllowed = true options.deliveryMode = .highQualityFormat let imgManager = PHImageManager.default() let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)] let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) print("targetSize for request", targetSize!) imgManager.requestImage(for: fetchResult.lastObject!, targetSize: targetSize!, contentMode: .default, options: options) { (result, info) in guard let result = result else { return } DispatchQueue.main.async(execute: { self.photoImageView.image = result self.collectionView.reloadData() }) } } fileprivate let collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) cv.translatesAutoresizingMaskIntoConstraints = false cv.register(CustomCell.self, forCellWithReuseIdentifier: "PreviewCell") return cv }()}extension PhotoViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize { return CGSize(width: collectionView.frame.width/5, height: collectionView.frame.width/4) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int { return 11 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PreviewCell", for: indexPath) as! CustomCell cell.bgImage = self.photoImageView.image if indexPath.row == 0 { cell.labelText = "A" } if indexPath.row == 1 { cell.labelText = "B" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectChrome", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 2 { cell.labelText = "C" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectInstant", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 3 { cell.labelText = "D" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectNoir", filterEffectValue: nil, filterEffectValueName: kCIInputImageKey)) } if indexPath.row == 4 { cell.labelText = "E" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectMono", filterEffectValue: nil, filterEffectValueName: kCIInputImageKey)) } if indexPath.row == 5 { cell.labelText = "F" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIExposureAdjust", filterEffectValue: 1, filterEffectValueName: kCIInputEVKey)) } if indexPath.row == 6 { cell.labelText = "G" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CISRGBToneCurveToLinear", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 7 { cell.labelText = "H" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectTransfer", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 8 { cell.labelText = "I" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIColorPosterize", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 9 { cell.labelText = "J" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIPhotoEffectProcess", filterEffectValue: nil, filterEffectValueName: nil)) } if indexPath.row == 10 { cell.labelText = "K" guard cell.bgImage != nil else { return cell } cell.bgImage = effects.applyFilterTo(image: photoImageView.image!, filterEffect: Effects.Filter(filterName: "CIVignetteEffect", filterEffectValue: nil, filterEffectValueName: nil)) } return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -&gt; UIEdgeInsets { return UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -&gt; CGFloat { return 1 } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PreviewCell", for: indexPath) as! CustomCell // cell.bgImage = self.photoImageView.image let imgArr = [cell.bgImage] photoImageView.image = imgArr[indexPath.row] photoImageView.reloadInputViews() }}class CustomCell: UICollectionViewCell { fileprivate let bg: UIImageView = { let iv = UIImageView() iv.translatesAutoresizingMaskIntoConstraints = false iv.contentMode = .scaleAspectFit iv.clipsToBounds = true return iv }() var bgImage: UIImage? { get { bg.image } set { bg.image = newValue } } fileprivate let label: UILabel = { let il = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20)) il.translatesAutoresizingMaskIntoConstraints = false il.contentMode = .scaleAspectFit il.clipsToBounds = true return il }() var labelText: String? { // #### get { label.text } set { label.text = newValue } } override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(bg) contentView.addSubview(label) bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }}extension PhotoViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { photoImageView.image = image } dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true, completion: nil) }}
12
0
3.2k
Apr ’20
Prototype collection view section header or footer views must have reuse identifiers
Hi, even though I have registered the footer with a reuseIdentifier and called it in viewForSupplementaryElementOfKind and set up it's referenceSizeForFooterInSection, I have been getting the error in the title. Could you please help ? fileprivate let collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) cv.translatesAutoresizingMaskIntoConstraints = false cv.register(CustomCell.self, forCellWithReuseIdentifier: "PreviewCell") cv.register(CustomCell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "FooterCell") return cv }() func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -&gt; UICollectionReusableView { if kind == UICollectionView.elementKindSectionFooter { let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! CustomCell footer.backgroundColor = .blue return footer } else { assert(false, "Unexpected element kind") } } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -&gt; CGSize { return CGSize(width: view.frame.width, height: 10) }
7
0
1.5k
Apr ’20
Show only tabBar items, hide rest of its' tabBarController view programmatically ?
Hello, I've created a UITabBarController programmatically with 3 tabBar items. When I tap on another view, a new tabBarController is pushed on to the view with the tabBar items, as I want. How can I show only the tabBar items (not the rest of its' view) with a tap on the other view ? I would like to see only the tabBar items appear on the previous viewController with a tap. As, I don't have a viewcontroller to work with on the storyboard, is it possible to do this programmatically ?Thanks very much in advance.
1
0
2.1k
Apr ’20
collectionView pictures not appearing without sliding
The collectionView pictures only start appearing if I slide them horizontally to the left. I've tried numerous solutions but couldn't solve it. If I assign the collectionView cells a background color, it works perfectly. But assigning the image of the "photoImageView" causes the problem. I must be missing something. "collectionView.reloadData()" doesn't solve the problem. Any advice please ?import Foundationimport UIKitimport Photosclass PhotoViewController: UIViewController { @IBOutlet weak var photoImageView: UIImageView! @IBOutlet weak var peeTabBar: UITabBar! @IBOutlet var photoView: UIView! var imagePicker = UIImagePickerController() override func viewDidLoad() { super.viewDidLoad() imagePicker.delegate = self assignTap() view.addSubview(collectionView) collectionView.backgroundColor = .white collectionView.topAnchor.constraint(equalTo: photoImageView.bottomAnchor, constant: 110).isActive = true collectionView.clipsToBounds = true collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 10).isActive = true collectionView.bottomAnchor.constraint(equalTo: peeTabBar.topAnchor, constant: -20).isActive = true collectionView.dataSource = self collectionView.delegate = self } func assignTap() { let tap = UITapGestureRecognizer(target: self, action: #selector(touchTapped(_:))) photoView.addGestureRecognizer(tap) } @objc func touchTapped(_ sender: UITapGestureRecognizer) { peeTabBar.isHidden = !peeTabBar.isHidden } func chooseImage(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { imagePicker.sourceType = .photoLibrary imagePicker.allowsEditing = true self.present(imagePicker,animated: true, completion: nil) } } func accessVideo(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.camera) { imagePicker.sourceType = .camera self.present(imagePicker, animated: true, completion: nil) } else { print("Camera not available") } } public func chooseLastImage(_ sender: Any) { print("photoImageView", photoImageView!) print("photoImageView.bounds", photoImageView.bounds) let targetSize: CGSize? = CGSize(width: photoImageView.bounds.width, height: photoImageView.bounds.height) let options = PHImageRequestOptions() options.isNetworkAccessAllowed = true options.deliveryMode = .highQualityFormat let imgManager = PHImageManager.default() let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)] let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) print("targetSize for request", targetSize!) //What is its value imgManager.requestImage(for: fetchResult.lastObject!, targetSize: targetSize!, contentMode: .default, options: options) { (result, info) in guard let result = result else { return } DispatchQueue.main.async(execute: { self.photoImageView.image = result }) } } fileprivate let collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) cv.translatesAutoresizingMaskIntoConstraints = false cv.register(CustomCell.self, forCellWithReuseIdentifier: "PreviewCell") return cv }()}extension PhotoViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize { return CGSize(width: collectionView.frame.width/5, height: collectionView.frame.width/4) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int { return 11 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PreviewCell", for: indexPath) as! CustomCell DispatchQueue.main.async { cell.bgImage = self.photoImageView.image } return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -&gt; UIEdgeInsets { return UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -&gt; CGFloat { return 5 }}class CustomCell: UICollectionViewCell { fileprivate let bg: UIImageView = { let iv = UIImageView() iv.translatesAutoresizingMaskIntoConstraints = false iv.contentMode = .scaleAspectFit iv.clipsToBounds = true return iv }() var bgImage: UIImage? { get { bg.image } set { bg.image = newValue } } override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(bg) bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }}extension PhotoViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { photoImageView.image = image } dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true, completion: nil) }}
2
0
1.8k
Mar ’20
Accessing another viewController's image from CustomCell Class
I would like to access "photoImageView" outlet or the function "chooseLastImage" from the "CustomCell" class, "let iv = UIImageView()", in order to have the same picture on "photoImageView" ,and "let iv = UIImageView()" in the collectionView. Any advice please ? import Foundationimport UIKitimport Photosclass PhotoViewController: UIViewController { @IBOutlet weak var photoImageView: UIImageView! @IBOutlet weak var peeTabBar: UITabBar! @IBOutlet var photoView: UIView! var imagePicker = UIImagePickerController() override func viewDidLoad() { super.viewDidLoad() imagePicker.delegate = self assignTap() view.addSubview(collectionView) collectionView.backgroundColor = .white collectionView.topAnchor.constraint(equalTo: photoImageView.bottomAnchor, constant: 110).isActive = true collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true collectionView.bottomAnchor.constraint(equalTo: peeTabBar.topAnchor, constant: -20).isActive = true collectionView.delegate = self collectionView.dataSource = self } func assignTap() { let tap = UITapGestureRecognizer(target: self, action: #selector(touchTapped(_:))) photoView.addGestureRecognizer(tap) } @objc func touchTapped(_ sender: UITapGestureRecognizer) { peeTabBar.isHidden = !peeTabBar.isHidden } func chooseImage(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { imagePicker.sourceType = .photoLibrary imagePicker.allowsEditing = true self.present(imagePicker,animated: true, completion: nil) } } func accessVideo(_ sender: Any) { if UIImagePickerController.isSourceTypeAvailable(.camera) { imagePicker.sourceType = .camera self.present(imagePicker, animated: true, completion: nil) } else { print("Camera not available") } } public func chooseLastImage(_ sender: Any) { print("photoImageView", photoImageView!) print("photoImageView.bounds", photoImageView.bounds) let targetSize: CGSize? = CGSize(width: photoImageView.bounds.width, height: photoImageView.bounds.height) let options = PHImageRequestOptions() options.isNetworkAccessAllowed = true options.deliveryMode = .highQualityFormat let imgManager = PHImageManager.default() let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)] let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) print("targetSize for request", targetSize!) //What is its value imgManager.requestImage(for: fetchResult.lastObject!, targetSize: targetSize!, contentMode: .default, options: options) { (result, info) in guard let result = result else { return } DispatchQueue.main.async(execute: { self.photoImageView.image = result }) } } fileprivate let collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) cv.translatesAutoresizingMaskIntoConstraints = false cv.register(CustomCell.self, forCellWithReuseIdentifier: "PreviewCell") return cv }()}extension PhotoViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -&gt; CGSize { return CGSize(width: collectionView.frame.width/5, height: collectionView.frame.width/5) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int { return 11 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PreviewCell", for: indexPath) as! CustomCell cell.backgroundColor = .red return cell }}class CustomCell: UICollectionViewCell { fileprivate let bg: UIImageView = { let iv = UIImageView() iv.translatesAutoresizingMaskIntoConstraints = false iv.contentMode = .scaleAspectFill iv.clipsToBounds = true return iv }() override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(bg) bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }}extension PhotoViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { photoImageView.image = image } dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true, completion: nil) }}
10
0
1.2k
Mar ’20
PHImageManager Error
The function is called from the previous viewController, the code compiles succesfully. When I run it and click the tableView row that calls this function, I receive "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value", underlining the "targetSize" causing the error. After I set a debug breakpoint on the "targetSize" and step over the error, it takes me back to the "photoImageView" outlet(which is properly connected to the storyboardy) then back to the "targetSize"Any help please ?public func chooseLastImage(_ sender: Any) { let scale = UIScreen.main.scale let targetSize: CGSize? = CGSize(width: photoImageView.bounds.width * scale, height: photoImageView.bounds.height * scale) let options = PHImageRequestOptions() options.isNetworkAccessAllowed = true options.deliveryMode = .highQualityFormat let imgManager = PHImageManager.default() let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key:"lastCreationDate", ascending: true)] let fetchResult: PHFetchResult&lt;PHAsset&gt; = PHAsset.fetchAssets(with: (.image), options: fetchOptions) imgManager.requestImage(for: fetchResult.lastObject!, targetSize: targetSize!, contentMode: .default, options: options) { (result, info) in guard let result = result else { return } DispatchQueue.main.async(execute: { self.photoImageView.image = result }) } }}
13
0
1.6k
Mar ’20